Implement the phases

In this part of the assignment, we will fill in the placeholder implementations of our phases, so that the compiler produces a PDF of a provided regular expression.

1 Fill in the implementations

In src/Phases.hs, provide a working implementation for each of the phases. You can ignore the compiler flags for now. Just implement the basics of the phase.

Below are some implementation hints. Use them to dial in the level of challenge you would like for this assignment! You can, of course, always ask for more help!

Here are some suggested steps, to complete this part.

  1. Port over the implementation of the evaluation, optimization, and compilation from the previous assignment. You can use your implementation(s), or the sample solution, or some combination thereof. To do so, you should be able to copy those files into the src directory for this assignment. Note that there is already a file for optimization in this assignment, so you will probably want to copy/paste the contents of the previous solution into that file.
  2. Build the project, to make sure everything seems to be in order.
  3. Implement the phases in src/Phases.hs. You will need to import some of the code that you just added to the project.

It may help to know that the tokenize function from the lexer has type

String -> CompilerM [Token]

To get this function into the Phase module, you can import it like so:

import Lexer (tokenize)

It may help to know that the parser function from the parser has type

[Token] -> CompilerM Regex

To get this function into the Phase module, you can import it like so:

import Parser (regexParser)

The optimize function returns a value of type Regex. However, the phase must return a monadic version of this value…

The generatePDF function in src/Compilation.hs is our emitter. Using the previous assignment, remind yourself how to call it!

The alphabet function in src/Evaluation.hs may also be helpful, when calling generatePDF.

The generatePDF function returns a value of type IO (). The emit phase must instead return a value of type CompilerM (). This means we must somehow “convert” the IO monad to the CompilerM monad. The Control.Monad.RWS module has a function named liftIO that does the job!

2 Optional: Implement compiler flag(s)

Consider implementing at least one of the compiler flags, for example the one that enables optimization (disabled by default).

To implement the flags, we will need to take advantage of some of the pieces of our monad stack. Here are some helper functions that operate on the context, writer, state, and error portions of our monad:

ask :: CompilerM CompilerContext
A function that retrieves the context. Exported by module Control.Monad.RSW (so it needs to be imported).
tell :: CompilerLog -> CompilerM ()
A function that appends a given log to the existing log. Exported by module Control.Monad.RSW (so it needs to be imported).
throwError :: CompilerError -> CompilerM a
A function that indicates an error, with a given value of type CompilerError. Exported by module Control.Monad.Except.
get :: CompilerM CompilerState
A function that retrieves the state. Exported by library module Control.Monad.RSW. You probably will not need state to implement any of the flags.
put :: CompilerState -> CompilerM ()
A function that replaces (i.e., overwrites) the state. Exported by library module Control.Monad.RSW. You probably will not need state to implement any of the flags.

In addition to some of the functions mentioned above, you will also need to import information about the context and the arguments to the compiler. These two lines should import everything you need (but you will probably still need to figure out how to use the imported functionality):

import CompilerTypes (CompilerContext(..))
import Args (Options (..))

3 Consider improvements

There is nothing to turn in for this part! For now, just make some notes. You will revisit them in a future assignment.

Identify two or three things that could be improved about the compiler. What part(s) of the project would you have to modify, to make the improvements?